import {BrowserWindow, app} from 'electron';
import {TabManager} from './TabManager';
import path from "node:path";
import {__DIRNAME, DEFAULT_URL, RENDERER_DIST, VITE_DEV_SERVER_URL} from "./ElectronConstant.ts";
import { logger, LogCategory } from '../logger';

interface WindowState {
  win: BrowserWindow;
  tabManager: TabManager;
}

// 保存窗口位置和大小的接口
interface SavedWindowState {
  x?: number;
  y?: number;
  width: number;
  height: number;
  isMaximized?: boolean;
}

/**
 * 窗口管理器类
 * 负责创建、管理和跟踪应用程序的所有窗口
 */
export class WindowManager {
  private static instance: WindowManager;
  private windows = new Map<number, WindowState>();
  private lastFocusedWindowId: number | null = null;

  private constructor() {
    // 私有化构造函数防止外部实例化
    logger.info('WindowManager', LogCategory.WINDOW, 'WindowManager初始化');

    // 监听窗口获取焦点事件，记录最后活跃的窗口
    app.on('browser-window-focus', (_, window) => {
      this.lastFocusedWindowId = window.id;
      logger.debug('WindowManager', LogCategory.WINDOW, `窗口获得焦点: ${window.id}`);
    });
  }

  /**
   * 获取WindowManager单例实例
   * @returns WindowManager实例
   */
  public static getInstance(): WindowManager {
    if (!WindowManager.instance) {
      WindowManager.instance = new WindowManager();
    }
    return WindowManager.instance;
  }

  /**
   * 获取当前活跃窗口
   * @returns 活跃的BrowserWindow或null
   */
  public getActiveWindow(): BrowserWindow | null {
    if (this.lastFocusedWindowId && this.windows.has(this.lastFocusedWindowId)) {
      return this.windows.get(this.lastFocusedWindowId)?.win || null;
    }

    // 如果没有记录的活跃窗口，返回第一个窗口
    if (this.windows.size > 0) {
      const firstWindowId = [...this.windows.keys()][0];
      return this.windows.get(firstWindowId)?.win || null;
    }

    return null;
  }

  /**
   * 创建新窗口
   * @param initialUrl 初始URL
   * @param windowState 窗口状态
   * @returns 窗口ID
   */
  public createWindow(initialUrl = DEFAULT_URL, windowState?: SavedWindowState): number {
    try {
      logger.info('WindowManager', LogCategory.WINDOW, `创建新窗口, URL: ${initialUrl}`);

      // 默认窗口配置
      const defaultOptions = {
        minWidth: 800,
        minHeight: 600,
        width: 1200,
        height: 800,
        icon: path.join(process.env.VITE_PUBLIC, 'electron-vite.svg'),
        // 隐藏原生标题栏但保留窗口控制按钮
        titleBarStyle: 'hidden' as const,
        // 开启原生窗口操作
        titleBarOverlay: {
          color: 'rgba(0, 0, 0, 0)',
          height: 40,
          symbolColor: '#000000',
        },
        frame: false, // 无边框窗口
        webPreferences: {
          preload: path.join(__DIRNAME, 'preload.mjs'),
          nodeIntegration: false,
          // 确保预加载脚本和Electron的内部逻辑在独立的上下文中运行，不建议修改
          contextIsolation: true,
          // 禁用webview标签
          webviewTag: false,
          // 启用沙箱模式确保安全性
          sandbox: true,
          // 启用CORS支持
          webSecurity: true,
          // 禁用同源策略，允许跨域请求
          allowRunningInsecureContent: false,
        },
      };

      // 应用保存的窗口状态（如果有）
      const winOptions = windowState ? {
        ...defaultOptions,
        width: windowState.width,
        height: windowState.height,
        ...(windowState.x !== undefined && windowState.y !== undefined ? { x: windowState.x, y: windowState.y } : {})
      } : defaultOptions;

      const win = new BrowserWindow(winOptions);

      // 如果保存的状态显示窗口是最大化的，则最大化窗口
      if (windowState?.isMaximized) {
        win.maximize();
      }

      const tabManager = new TabManager(win);
      this.windows.set(win.id, {win, tabManager});
      this.lastFocusedWindowId = win.id;

      // 加载渲染进程
      this.loadWindowContent(win);

      // 窗口关闭时的清理
      win.on('closed', () => {
        logger.info('WindowManager', LogCategory.WINDOW, `窗口关闭: ${win.id}`);
        tabManager.destroy();
        this.windows.delete(win.id);

        // 如果所有窗口都被关闭，重置最后活跃窗口ID
        if (this.windows.size === 0) {
          this.lastFocusedWindowId = null;
        }
      });

      // 创建初始标签页
      tabManager.createTab(initialUrl);

      logger.info('WindowManager', LogCategory.WINDOW, `窗口创建成功, ID: ${win.id}`);
      return win.id;
    } catch (error) {
      logger.error('WindowManager', LogCategory.WINDOW, '创建窗口失败', error);
      throw new Error(`创建窗口失败: ${error}`);
    }
  }

  /**
   * 获取所有窗口
   * @returns 所有窗口的数组
   */
  public getAllWindows(): BrowserWindow[] {
    return [...this.windows.values()].map(state => state.win);
  }

  /**
   * 获取窗口数量
   * @returns 窗口数量
   */
  public getWindowCount(): number {
    return this.windows.size;
  }

  /**
   * 保存窗口状态
   * @param windowId 窗口ID
   * @returns 保存的窗口状态或null
   */
  public saveWindowState(windowId: number): SavedWindowState | null {
    try {
      const windowState = this.windows.get(windowId);
      if (!windowState) return null;

      const { win } = windowState;
      const bounds = win.getBounds();

      const state = {
        x: bounds.x,
        y: bounds.y,
        width: bounds.width,
        height: bounds.height,
        isMaximized: win.isMaximized()
      };

      logger.debug('WindowManager', LogCategory.WINDOW, `保存窗口状态: ${windowId}`, state);
      return state;
    } catch (error) {
      logger.error('WindowManager', LogCategory.WINDOW, `保存窗口状态失败: ${windowId}`, error);
      return null;
    }
  }

  /**
   * 获取指定窗口的标签管理器
   * @param windowId 窗口ID
   * @returns TabManager实例或undefined
   */
  public getTabManager(windowId: number): TabManager | undefined {
    const state = this.windows.get(windowId);
    return state?.tabManager;
  }

  /**
   * 加载窗口内容
   * @param win BrowserWindow实例
   * @private
   */
  private loadWindowContent(win: BrowserWindow) {
    try {
      if (VITE_DEV_SERVER_URL) {
        logger.debug('WindowManager', LogCategory.WINDOW, `开发模式: 加载开发服务器URL: ${VITE_DEV_SERVER_URL}`);
        win.loadURL(VITE_DEV_SERVER_URL);
      } else {
        const distPath = path.join(RENDERER_DIST, 'index.html');
        logger.debug('WindowManager', LogCategory.WINDOW, `生产模式: 加载文件: ${distPath}`);
        win.loadFile(distPath);
      }
    } catch (error) {
      logger.error('WindowManager', LogCategory.WINDOW, '加载窗口内容失败', error);
      throw new Error(`加载窗口内容失败: ${error}`);
    }
  }

  /**
   * 清理所有窗口并释放资源
   */
  public clear() {
    logger.info('WindowManager', LogCategory.WINDOW, `清理所有窗口, 数量: ${this.windows.size}`);

    // 关闭所有窗口
    for (const [windowId, state] of this.windows.entries()) {
      try {
        state.tabManager.destroy();
        if (!state.win.isDestroyed()) {
          state.win.close();
        }
      } catch (e) {
        logger.error('WindowManager', LogCategory.WINDOW, `关闭窗口${windowId}失败`, e);
      }
    }

    // 清空窗口映射
    this.windows.clear();
    this.lastFocusedWindowId = null;
    logger.info('WindowManager', LogCategory.WINDOW, '所有窗口清理完成');
  }
}
